﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Psm.PubSub.Configuration;

namespace Psm.PubSub.StateCache
{
    public class SchemaCollection
    {
        private static IDictionary<string,Schema> allSchemas = new Dictionary<string,Schema>();

        public static IDictionary<string, Schema> AllSchemas
        {
            get
            {
                return allSchemas;
            }
        }

        static SchemaCollection()
        {
            if( PubSub.Configuration.PubSubConfiguration.Instance != null )
                foreach (TopicConfiguration topicConfig in PubSub.Configuration.PubSubConfiguration.Instance.Topics)
                {
                    allSchemas.Add(topicConfig.Name, new Schema(topicConfig));
                }
        }
    }

    public class Schema
    {
        public string Topic { get; private set; }
        public IList<SchemaField> KeyFields { get; private set; }
        public IList<SchemaField> Fields {get; private set;}
        private IDictionary<string, SchemaField> fieldsHash;

        public Schema(string topic)
        {
            this.Topic = topic;
            this.Fields = new List<SchemaField>();
            this.KeyFields = new List<SchemaField>();
            this.fieldsHash = new Dictionary<string,SchemaField>();
        }

        public Schema(TopicConfiguration topicConfig):
            this(topicConfig.Name)
        {   
            foreach (FieldConfiguration fieldConfig in topicConfig.Fields)
            {
                SchemaField field = new SchemaField(fieldConfig.Name, fieldConfig.Type, null, fieldConfig.IsKey, this.Fields.Count);
                AddField(field);

                if (field.IsKey) this.KeyFields.Add(field);
            }
        }
        
        public SchemaField GetField(string name)
        {
            if (fieldsHash.ContainsKey(name)) return fieldsHash[name];
            return null;
        }

        public void AddField( SchemaField field)
        {
            this.Fields.Add(field);
            if( field.IsKey )
                this.KeyFields.Add(field);
            fieldsHash.Add(field.Name, field);
        }
    }

    public class SchemaField
    {
        public string Name { get; private set; }
        public string Type { get; private set; }
        public IList<string> Synonyms { get; private set;}
        public bool IsKey { get; private set;}
        public int Index { get; private set; }

        public SchemaField(string name, string type, string[] synonyms, bool isKey, int index)
        {
            this.Name = name;
            this.Type = type;
            this.Synonyms = new List<string>(synonyms ?? new string[0]) ;
            this.IsKey = isKey;
            this.Index = index;
        }
    }
}
